home *** CD-ROM | disk | FTP | other *** search
Text File | 1991-06-13 | 9.7 KB | 521 lines | [TEXT/MPS ] |
- ;These macros are for the 68000.
- ;They have not been optimized for the 68010, 68020 or 68030.
-
- ;Some of these macros work only in supervisor mode on a
- ;68000 due to use of screwed up CCR instructions.
-
- ;Do an EQU if the symbol is not already defined.
- MACRO
- &symbol Default &value
- IF &Type(&symbol)='UNDEFINED' THEN
- &symbol: EQU &value
- ENDIF
- ENDM
-
- ;Ensure that a condition is true.
- MACRO
- Ensure &condition
- IF &Eval(&condition)=0 THEN
- AERROR 'Ensure failed.'
- ENDIF
- ENDM
-
- ;End a RECORD and declare a size field.
- MACRO
- ENDRSize
- ORG
- size: EQU *
- ENDR
- ENDM
-
- ;Reserve space on a stack.
- MACRO
- RSRV.&size &number
- LCLA &bytes
- IF &number = '' THEN
- &bytes: SETA 1
- ELSE
- &bytes: SETA &Eval(&number)
- ENDIF
- IF &size='L' THEN
- &bytes: SETA 4*&bytes
- ELSEIF &size='W' THEN
- &bytes: SETA 2*&bytes
- ELSEIF &size='B' THEN
- ELSE
- AERROR &CONCAT('RSRV: ',&size,' is a bad size.')
- ENDIF
- &bytes: SETA ((&bytes+1) AND (~1))
- IF &bytes<32767 THEN
- SUB.W #&bytes,SP
- ELSE
- SUB.L #&bytes,SP
- ENDIF
- ENDM
-
- ;Free space from a stack.
- MACRO
- FREE.&size &number
- LCLA &bytes
- IF &number = '' THEN
- &bytes: SETA 1
- ELSE
- &bytes: SETA &Eval(&number)
- ENDIF
- IF &size='L' THEN
- &bytes: SETA 4*&bytes
- ELSEIF &size='W' THEN
- &bytes: SETA 2*&bytes
- ELSEIF &size='B' THEN
- ELSE
- AERROR &CONCAT('FREE: ',&size,' is a bad size.')
- ENDIF
- &bytes: SETA ((&bytes+1) AND (~1))
- IF &bytes<32767 THEN
- ADD.W #&bytes,SP
- ELSE
- ADD.L #&bytes,SP
- ENDIF
- ENDM
-
- ;Move condition codes.
- MACRO
- MOVECCR &destination
- MOVE.W SR,&destination
- ENDM
-
- ;Save some registers on the stack, possibly changing the condition codes.
- MACRO
- Save ®isters,&preserve==0
- GBLC &savedRegisters
- GBLA &port
- IF &savedRegisters<>'' THEN
- AERROR 'Two Saves without an intervening Restore.'
- ENDIF
- &port: SETA 0
- IF ®isters='' THEN
- &savedRegisters: SETC 'None'
- ELSEIF ®isters='thePort' THEN
- &savedRegisters: SETC 'None'
- &port: SETA 1
- ELSE
- IF &SubStr(®isters,&Len(®isters)-7,8)='/thePort' THEN
- &savedRegisters: SETC &SubStr(®isters,1,&Len(®isters)-8)
- &port: SETA 1
- ELSE
- &savedRegisters: SETC ®isters
- ENDIF
- IF &SubStr(&Type(&savedRegisters),1,5)='REG A' THEN
- MOVE.L &savedRegisters,-(SP)
- ELSEIF &SubStr(&Type(&savedRegisters),1,4)='REG ' THEN
- IF &preserve THEN
- MOVEM.L &savedRegisters,-(SP)
- ELSE
- MOVE.L &savedRegisters,-(SP)
- ENDIF
- ELSE
- MOVEM.L &savedRegisters,-(SP)
- ENDIF
- ENDIF
- IF &port THEN
- RSRV.L
- MOVEM.L D0-D2/A0-A1,-(SP)
- IF &preserve THEN
- MOVECCR -(SP)
- PEA 2+5*4(SP)
- ELSE
- PEA 5*4(SP)
- ENDIF
- _GetPort
- IF &preserve THEN
- MOVE.W (SP)+,CCR
- ENDIF
- MOVEM.L (SP)+,D0-D2/A0-A1
- ENDIF
- IF debug THEN
- PEA ('Save')
- ENDIF
- ENDM
-
- ;Restore some registers saved by a Save macro.
- MACRO
- Restore &preserve==0
- GBLC &savedRegisters
- GBLA &port
- IF &savedRegisters='' THEN
- AERROR 'Restore without Save.'
- ELSE
- IF debug THEN
- IF &preserve THEN
- MOVECCR -(SP)
- CMP.L #'Save',2(SP)
- ELSE
- CMP.L #'Save',(SP)+
- ENDIF
- BEQ.S @goodSave
- _Debugger
- @goodSave:
- IF &preserve THEN
- MOVE.W (SP)+,CCR
- ADDQ.W #4,SP
- ENDIF
- ENDIF
- IF &port THEN
- IF &preserve THEN
- MOVECCR -(SP)
- MOVE.L 2(SP),-(SP)
- _SetPort
- MOVE.W (SP)+,CCR
- FREE.L
- ELSE
- MOVEM.L D0-D2/A0-A1,-(SP)
- IF &preserve THEN
- MOVECCR -(SP)
- MOVE.L 2+5*4(SP),-(SP)
- ELSE
- MOVE.L 5*4(SP),-(SP)
- ENDIF
- _SetPort
- IF &preserve THEN
- MOVE.W (SP)+,CCR
- ENDIF
- MOVEM.L (SP)+,D0-D2/A0-A1
- FREE.L
- ENDIF
- ENDIF
- IF &savedRegisters<>'None' THEN
- IF &SubStr(&Type(&savedRegisters),1,5)='REG A' THEN
- MOVE.L (SP)+,&savedRegisters
- ELSEIF &SubStr(&Type(&savedRegisters),1,4)='REG ' THEN
- IF &preserve THEN
- MOVEM.L (SP)+,&savedRegisters
- ELSE
- MOVE.L (SP)+,&savedRegisters
- ENDIF
- ELSE
- MOVEM.L (SP)+,&savedRegisters
- ENDIF
- ENDIF
- &savedRegisters: SETC ''
- ENDIF
- ENDM
-
- ;Pad a piece of memory to BlockSize items (item is either bytes, words, or longs).
- MACRO
- Pad.&size &blockSize,&startLabel,&itemValue=0
- LCLC &itemType
- LCLA &padItems
- &PadItems: SETA &Eval(&BlockSize)-(*-&Eval(&StartLabel))
- IF &size='' THEN
- &itemType: SETC 'B'
- ELSEIF &size='B' THEN
- &itemType: SETC 'B'
- ELSEIF &size='W' THEN
- &ItemType: SETC 'W'
- &padItems: SETA &padItems DIV 2
- ELSEIF &size='L' THEN
- &itemType: SETC 'L'
- &padItems: SETA &padItems DIV 4
- ELSE
- AERROR &Concat('Pad cannot handle unknown item length: ',&size)
- ENDIF
- IF &padItems<0 THEN
- AERROR 'Pad cannot pad a block bigger than the block size.'
- ELSEIF &padItems>0 THEN
- DCB.&itemType &padItems,&itemValue
- ENDIF
- ENDM
-
- ;Create a jump table starting with the label and having a given prefix.
- MACRO
- &name Table &prefix,&base
- LCLC &tableName
- GBLC &tablePrefix,&tableBase
- IF &name = '' THEN
- &tableName: SETC 'Table'
- ELSE
- &tableName: SETC &name
- ENDIF
- &tablePrefix: SETC &prefix
- IF &base = '' THEN
- &tableBase: SETC &tableName
- ELSEIF &UpCase(&base) = 'ABSOLUTE' THEN
- &tableBase: SETC ''
- ELSE
- &tableBase: SETC &base
- ENDIF
- &tableName:
- ENDM
-
- ;Create a jump table entry.
- MACRO
- DT.&size &entry
- GBLC &tablePrefix,&tableBase
- IF &tableBase = '' THEN
- DC.&size &Concat(&tablePrefix,&entry)
- ELSE
- DC.&size &Concat(&tablePrefix,&entry,'-',&tableBase)
- ENDIF
- ENDM
-
- ;Create a stack frame.
- MACRO
- &frame Frame ¶meters=0
- GBLC &frameName,&frameState,&WITHStatus,&ENDWITHMod
- IF &WITHStatus = 'NeedENDWITH' THEN
- IF &SysMod = &ENDWITHMod THEN
- ENDWITH
- ENDIF
- ENDIF
- &WITHStatus: SETC ''
- IF &frameState = '' THEN
- IF &frame = '' THEN
- &frameName: SETC 'Frame'
- ELSE
- &frameName: SETC &frame
- ENDIF
- &frameName: RECORD {Link},DECR
- FrameStart: EQU *
- &frameState: SETC 'Frame'
- ENDIF
- IF &frameState = 'Frame' THEN
- IF ¶meters = 0 THEN
- ORG
- ParameterSize: EQU FrameStart-*
- Return: DS.L 1
- Link: DS.L 1
- &frameState: SETC 'Link'
- ENDIF
- ELSE
- AERROR 'Two Frames without intervening EndFrame.'
- ENDIF
- ENDM
-
- ;Declare some parameters.
- MACRO
- &Frme ParameterFrame
- &Frme Frame parameters=1
- ENDM
-
- ;Declare some locals.
- MACRO
- LocalFrame
- Frame parameters=0
- ENDM
-
- ;End a stack frame.
- MACRO
- EndFrame
- GBLC &frameName,&frameState,&WITHStatus
- IF &frameState = 'Frame' THEN
- Frame
- ENDIF
- IF &frameState = 'Link' THEN
- ORG
- LocalSize: EQU *
- ENDR
- &frameState: SETC ''
- &WITHStatus: SETC 'NeedWITH'
- ELSE
- AERROR 'EndFrame without proper balancing Frame.'
- ENDIF
- ENDM
-
- ;Hide the cursor.
- MACRO
- HideCursor
- _HideCursor
- ENDM
-
- ;Show the cursor.
- MACRO
- ShowCursor
- MOVE.B #1,CrsrBusy ;lock out the cursor routines
- CMP.W #-1,CrsrState ;will the cursor be made visible?
- BLT.S @doShow ;no, don't unobscure
- CLR.B CrsrObscure ;turn off the obscure flag
- @doShow:
- _ShowCursor ;start the cursor back up
- ENDM
-
- ;LINK.
- MACRO
- doLINK &size
- GBLC &LINKstate,&frameName,&WITHStatus,&ENDWITHMod
- IF &LINKstate <> '' THEN
- AERROR 'missing UNLK'
- ENDIF
- IF &WITHStatus = 'NeedWITH' THEN
- WITH &frameName
- &WITHStatus: SETC 'NeedENDWITH'
- &ENDWITHMod: SETC &SysMod
- ENDIF
- IF &size='' THEN
- LINK A6,#LocalSize
- ELSE
- LINK A6,#&size
- ENDIF
- IF debug THEN
- PEA ('LINK')
- ENDIF
- &LINKState: SETC 'doLINK'
- ENDM
-
- ;Fake LINK.
- MACRO
- noLINK
- GBLC &LINKstate
- IF &LINKstate <> '' THEN
- AERROR 'missing UNLK'
- ENDIF
- IF debug THEN
- LINK A6,#0
- UNLK A6
- ENDIF
- &LINKState: SETC 'noLINK'
- ENDM
-
- ;UNLK.
- MACRO
- doUNLK &preserve==0
- GBLC &LINKstate
- IF &LINKstate = '' THEN
- AERROR 'missing LINK'
- ENDIF
- IF &LINKstate = 'doLINK' THEN
- IF debug THEN
- IF &preserve THEN
- MOVECCR -(SP)
- CMP.L #'LINK',2(SP)
- ELSE
- CMP.L #'LINK',(SP)+
- ENDIF
- BEQ.S @goodUNLK
- _Debugger
- @goodUNLK:
- IF &preserve THEN
- MOVE.W (SP)+,CCR
- ADDQ.W #4,SP
- ENDIF
- ENDIF
- UNLK A6
- ELSE
- IF debug THEN
- BRA.S @skipUNLK
- UNLK A6
- @skipUNLK:
- ENDIF
- ENDIF
- &LINKState: SETC ''
- ENDM
-
- ;Fake RTS.
- MACRO
- noRTS
- IF debug THEN
- BRA.S @skipRTS
- RTS
- @skipRTS:
- ENDIF
- ENDM
-
- ;RTS.
- MACRO
- doRTS
- RTS
- ENDM
-
- ;RTD (uses A0).
- MACRO
- doRTD &size
- LCLA &bytes
- IF &size = '' THEN
- &bytes: SETA ParameterSize
- ELSEIF &SubStr(&size, 1, 1) = '#' THEN
- &bytes: SETA &StrToInt(&SubStr(&size, 2, &Length(&size)-1))
- ELSE
- AERROR 'doRTD: bad size'
- ENDIF
- IF &bytes = 0 THEN
- RTS
- ELSEIF &bytes = 4 THEN
- MOVE.L (SP)+,(SP)
- RTS
- ELSEIF &bytes <= 8 THEN
- MOVE.L (SP)+,A0
- ADDQ.W #&bytes,SP
- JMP (A0)
- ELSE
- MOVE.L (SP)+,A0
- LEA &bytes(SP),SP
- JMP (A0)
- ENDIF
- ENDM
-
- ;Symbol.
- MACRO
- Symbol &routineName
- LCLC &name
- IF debug THEN
- IF &routineName='' THEN
- &name: SETC &SysMod
- ELSEIF &routineName[1]='''' THEN
- &name: SETC &SubStr(&routineName,2,&Len(&routineName)-2)
- ELSE
- &name: SETC &routineName
- ENDIF
- &name: SETC &SubStr(&Concat(&name, ' '),1,8)
- DC.B &Ord(&name[1])+$80,&Ord(&name[2]),&Ord(&name[3]),&Ord(&name[4])
- DC.B &Ord(&name[5]),&Ord(&name[6]),&Ord(&name[7]),&Ord(&name[8])
- ENDIF
- ENDM
-
- ;Define constant storage.
- MACRO
- DCS &recordName
- DCB.B &recordName..size,0
- ENDM
-
- ;Set up a patch table.
- MACRO
- PatchTable &thePatchStart
- GBLC &patchStart
- &patchStart: SETC &thePatchStart
- ENDM
-
- ;Set up a patch table entry.
- MACRO
- DP &key,&patch,&old
- GBLC &patchStart
- IF &key='' THEN
- DC.W 0
- ELSE
- DC.W &key
- IF &patch='' THEN
- DC.W 0
- ELSE
- DC.W Patch&patch-&patchStart
- ENDIF
- IF &old='' THEN
- DC.W 0
- ELSE
- DC.W Old&old-&patchStart
- ENDIF
- ENDIF
- ENDM
-
- ;Set up a JMP to be patched.
- MACRO
- PJMP &label
- DC.W $4EF9
- Old&label: DC.L 0
- ENDM
-
- ;Set up a JSR to be patched.
- MACRO
- PJSR &label
- DC.W $4EB9
- Old&label: DC.L 0
- ENDM
-
-